//
// Created by songpingwang on 25-7-8.
//

#ifndef UDATAFRAME_H
#define UDATAFRAME_H
#include "UDataBase.h"
#include <string_view>



namespace NDFrame {
    class UDataView;
    class UFrame_API UDataFrame final : public UDataBase {
    public:
        using VecItemPtr = std::vector<DataItem *>;
        using VecRE2Ptr = std::vector<const RE2*>;

        /**
         * @brief 默认构造函数
         */
        UDataFrame() = default;

        /**
         * @brief 指定容量的构造函数
         * @param capacity 预分配的容量大小
         */
        explicit UDataFrame(size_t capacity);

        /**
         * @brief 使用初始化列表构造UDataFrame
         * @param items 初始化数据项列表
         */
        UDataFrame(std::initializer_list<DataItem> items);

        /**
         * @brief 构造包含单个数据项的UDataFrame
         * @param idx 数据项索引
         * @param x0 左上角x坐标
         * @param y0 左上角y坐标
         * @param x1 右下角x坐标
         * @param y1 右下角y坐标
         * @param width 宽度
         * @param height 高度
         * @param page 页码
         * @param flags 标志位
         * @param text 文本内容
         * @param text_sep 分隔符文本
         */
        UDataFrame(int idx,int x0, int y0,int x1, int y1,
            int width, int height,int page, int flags,
            std::string&& text, std::string&& text_sep);

        /**
         * @brief 拷贝构造函数
         * @param other 被拷贝的对象
         */
        UDataFrame(const UDataFrame &other);

        /**
         * @brief 移动构造函数
         * @param other 被移动的对象
         */
        UDataFrame(UDataFrame &&other) noexcept;

        /**
         * @brief 析构函数，释放资源
         */
        ~UDataFrame() override { deallocate(); }

        /**
         * @brief 拷贝赋值运算符
         * @param other 被拷贝的对象
         * @return 当前对象的引用
         */
        UDataFrame &operator=(const UDataFrame &other);

        /**
         * @brief 移动赋值运算符
         * @param other 被移动的对象
         * @return 当前对象的引用
         */
        UDataFrame &operator=(UDataFrame &&other) noexcept;

        /**
         * @brief 克隆当前UDataFrame对象
         * @return 新的UDataFrame对象副本
         */
        MAYBE_USE UDataFrame clone() const { return UDataFrame{*this}; }

        /**
         * @brief 获取数据项数量
         * @return 当前数据项的数量
         */
        MAYBE_USE size_t size() const override { return this->m_size; }

        /**
         * @brief 清空所有数据
         */
        VOID_USE void clear();

        /**
         * @brief 设置数据项数量
         * @param size 新的数据项数量
         */
        VOID_USE void set_size(const size_t size) { this->m_size = size; }

        /**
         * @brief 判断是否为空
         * @return 如果没有数据项则返回true，否则返回false
         */
        MAYBE_USE bool empty() const override { return this->m_size == 0; }

        /**
         * @brief 获取数据项指针
         * @return 指向数据项数组的指针
         */
        MAYBE_USE DataItem *getItemPtr() const override { return this->ItemPtr.get(); }

        /**
         * @brief 获取当前容量
         * @return 当前分配的容量大小
         */
        MAYBE_USE size_t capacity() const { return this->m_capacity; }

        /**
         * @brief 在末尾添加数据项（拷贝版本）
         * @param item 要添加的数据项
         */
        VOID_USE void push_back(const DataItem &item);

        /**
         * @brief 在末尾添加数据项（移动版本）
         * @param item 要添加的数据项
         */
        VOID_USE void push_back(DataItem &&item);

        /**
         * @brief 访问指定索引的数据项（只读）
         * @param index 数据项索引
         * @return 指定索引的数据项引用
         */
        const DataItem &operator[](size_t index) const;

        /**
         * @brief 访问指定索引的数据项（可写）
         * @param index 数据项索引
         * @return 指定索引的数据项引用
         */
        DataItem &operator[](size_t index);

        /**
         * @brief 根据字段类型访问指定行的数据
         * @tparam field 字段枚举值
         * @param row 行号
         * @return 对应字段值的引用
         */
        template<Field field>
        auto& ix(size_t row);

        /**
         * @brief 根据字段类型访问指定行的数据（只读）
         * @tparam field 字段枚举值
         * @param row 行号
         * @return 对应字段值的常量引用
         */
        template<Field field>
        const auto& ix(size_t row) const;


        /**
         * @brief 预分配指定容量的内存空间
         * @param new_capacity 新的容量大小
         */
        void reserve(size_t new_capacity);

        /**
         * @brief 获取最后一个数据项的引用
         * @return 最后一个数据项的引用
         */
        DataItem &back() override;

        /**
         * @brief 获取第一个数据项的引用
         * @return 第一个数据项的引用
         */
        DataItem &front() override;

        /**
         * @brief 打印当前UDataFrame的内容
         */
        VOID_USE void print() const override { format_print(*this);}

    private:
        size_t m_size = 0;                      ///< 当前数据项数量
        size_t m_capacity = 0;                  ///< 当前分配的容量
        std::shared_ptr<DataItem[]> ItemPtr;    ///< 数据项指针数组
    public:

        /**
         * @brief 根据指定字段对数据进行排序
         * @tparam field 排序依据的字段
         * @param descending 是否降序排列，默认为false（升序）
         */
        template<Field field>
        void sort(bool descending=false);

        /**
         * @brief 对指定字段的所有值减去指定数值
         * @tparam field 操作的字段
         * @param num 要减去的数值
         */
        template<Field field>
        VOID_USE void sub(int num) noexcept;

        /**
         * @brief 对指定字段的所有值加上指定数值
         * @tparam field 操作的字段
         * @param num 要加上的数值
         * @param max_num 最大限制值
         */
        template<Field field>
        VOID_USE void add(int num, int max_num) noexcept;

        /**
         * @brief 计算指定字段的平均值
         * @tparam field 计算平均值的字段
         * @return 平均值
         */
        template<Field field>
        MAYBE_USE float mean_col() const;

        /**
         * @brief 查找指定字段的最大值
         * @tparam field 查找最大值的字段
         * @return 最大值
         */
        template<Field field>
        MAYBE_USE size_t max_col() const;

        /**
         * @brief 查找指定字段的最小值
         * @tparam field 查找最小值的字段
         * @return 最小值
         */
        template<Field field>
        MAYBE_USE size_t min_col() const;

        /**
         * @brief 获取指定字段每个元素的长度
         * @tparam field 获取长度的字段
         * @return 包含各元素长度的向量
         */
        template<Field field>
        MAYBE_USE std::vector<size_t> len() const;

        /**
         * @brief 获取指定字段值的引用包装器向量
         * @tparam field 获取值的字段
         * @tparam T 字段值的类型
         * @return 包含字段值引用包装器的向量
         */
        template<Field field, typename T>
        MAYBE_USE std::vector<std::reference_wrapper<T>> values_ref() const;

        /**
         * @brief 获取指定字段值的拷贝向量
         * @tparam field 获取值的字段
         * @tparam T 字段值的类型
         * @return 包含字段值拷贝的向量
         */
        template<Field field, typename T>
        MAYBE_USE std::vector<T> values() const;

        /**
         * @brief 合并满足条件的相邻行
         * @param width 宽度阈值
         * @param height 高度阈值
         * @param sep 合并时使用的分隔符
         * @return 合并后的新UDataFrame对象
         *
         * 合并条件：
         * 1. 限定宽(width)与高(height)
         * 2. 下一行的x0与本行的x1的绝对距离小于width
         * 3. 下一行的y0与本行的y0的绝对距离小于height
         *
         * 符合合并条件的操作：
         * 1. 将本行与下一行text使用sep字符进行合并
         * 2. (x0,y0)取这两行最小值
         * 3. (x1,y1,height)取这两行最大值
         * 4. 删除下一行
         */
        MAYBE_USE UDataFrame DF_merge_line(int width, int height, std::string_view sep);


        /**
         * @brief 重置索引
         *
         * 一般对筛选的子UDataFrame进行重置index
         * reset_index()直接对整个UDataFrame进行重置索引（无复制）
         */
        VOID_USE void reset_index() noexcept;

        /**
         * @brief 根据提供的指针创建新的UDataFrame对象
         * @param pointers 数据项指针向量
         * @return 新的UDataFrame对象（深拷贝）
         *
         * DF_pointers_to_df(VecItemPtr& pointers)创建一个由提供指针的新UDataFrame(深复制)
         */
        MAYBE_USE UDataFrame DF_pointers_to_df(const VecItemPtr &pointers) const;

        /**
         * @brief 删除指定指针指向的数据项并返回新UDataFrame对象
         * @param pointers 要删除的数据项指针向量
         * @return 删除指定数据项后的新UDataFrame对象（深拷贝）
         *
         * DF_drop_pointer 删除 std::vector<DataItem*>& pointers其中的指针,返回删除后的UDataFrame(深复制)
         * drop_pointer    删除 std::vector<DataItem*>& pointers其中的指针,就地删除
         */
        MAYBE_USE UDataFrame DF_drop_pointer(const VecItemPtr &pointers) const;

        /**
         * @brief 删除指定指针指向的数据项
         * @param pointers 要删除的数据项指针向量
         */
        VOID_USE void drop_pointer(const VecItemPtr &pointers);

        /**
         * @brief 判断指定字段的值是否在给定字符串集合中
         * @tparam field 检查的字段
         * @param texts 字符串集合
         * @param out_ptrs 输出参数，存储匹配的数据项指针
         * @return 是否存在匹配项
         *
         * 返回值：
         * - std::vector<size_t>& indices     返回符合条件的索引
         * - VecItemPtr& pointers             返回符合条件的UDataFrame的行指针
         * - UDataFrame& dataframe            返回符合条件的UDataFrame(深复制)
         */
        template<Field field>
        MAYBE_USE bool is_in(const std::vector<std::string> &texts, VecItemPtr &out_ptrs) const;

        /**
         * @brief 判断指定字段的值是否在给定字符串集合中
         * @tparam field 检查的字段
         * @param texts 字符串集合
         * @param out_df 输出参数，存储匹配的数据项构成的新UDataFrame
         * @return 是否存在匹配项
         */
        template<Field field>
        MAYBE_USE bool is_in(const std::vector<std::string> &texts, UDataFrame &out_df) const;

        /**
         * @brief 判断指定字段的值是否包含给定字符串集合中的任意一个
         * @tparam field 检查的字段
         * @param texts 字符串集合
         * @return 是否包含任意一个字符串
         */
        template<Field field>
        MAYBE_USE bool contains_any(const std::vector<std::string> &texts) const;


        /**
         * @brief 连接两个UDataFrame对象
         * @param df1 第一个UDataFrame对象
         * @param df2 第二个UDataFrame对象
         * @return 连接后的新UDataFrame对象
         */
        MAYBE_USE static UDataFrame concat(const UDataFrame &df1, const UDataFrame &df2);

        /**
         * @brief 使用指定分隔符合并指定字段的值
         * @tparam field 合并的字段
         * @param separator 分隔符
         * @return 合并后的字符串
         *
         * 仿照python的join函数，默认为空字符串
         */
        template<Field field>
        MAYBE_USE std::string join(std::string_view separator) const;

        /**
         * @brief 使用指定分隔符合并指定字段的值并在合并过程中替换字符
         * @tparam field 合并的字段
         * @param oldChar 要被替换的字符
         * @param newChars 替换后的字符串
         * @param separator 分隔符，默认为空字符串
         * @return 合并并替换后的字符串
         */
        template<Field field>
        MAYBE_USE std::string join_and_replace(
            char oldChar,
            std::string_view newChars,
            std::string_view separator = "") const;


        /**
         * @brief 替换指定字段中的字符
         * @tparam field_src 源字段
         * @tparam field_dst 目标字段
         * @param oldChar 要被替换的字符
         * @param newChar 替换后的字符
         */
        template<Field field_src, Field field_dst>
        VOID_USE void replace(char oldChar, char newChar);

        /**
         * @brief 替换指定字段中的多个字符
         * @tparam field_src 源字段
         * @tparam field_dst 目标字段
         * @param oldChar0 第一个要被替换的字符
         * @param newChar0 第一个替换后的字符
         * @param oldChar1 第二个要被替换的字符
         * @param newChar1 第二个替换后的字符
         */
        template<Field field_src, Field field_dst>
        VOID_USE void replace(char oldChar0, char newChar0, char oldChar1, char newChar1);

        /**
         * @brief 使用正则表达式替换指定字段中的内容
         * @tparam field_src 源字段
         * @tparam field_dst 目标字段
         * @param pattern 正则表达式模式
         * @param rewrite 替换文本
         */
        template<Field field_src, Field field_dst>
        VOID_USE void regex_replace(const RE2& pattern, std::string_view rewrite);


        /**
         * @brief 使用正则表达式提取指定字段中的内容并替换原内容
         * @tparam field 操作的字段
         * @param pattern_ 正则表达式模式
         *
         * 正则提取：替换为提取到的数据，否则清空数据
         */
        template<Field field>
        VOID_USE void regex_extract(const RE2 &pattern_);

        /**
         * @brief 使用正则表达式提取指定字段中的内容并返回新UDataFrame
         * @tparam field 操作的字段
         * @param pattern_ 正则表达式模式
         * @return 提取结果构成的新UDataFrame对象
         *
         * 正则提取：仅返回提取到的数据
         */
        template<Field field>
        MAYBE_USE UDataFrame DF_regex_extract(const RE2 &pattern_) const;


        /**
         * @brief 使用谓词函数过滤数据项
         * @tparam Predicate 谓词函数类型
         * @param out_pointers 输出参数，存储符合条件的数据项指针
         * @param predicate 谓词函数
         * @return 是否存在符合条件的数据项
         *
         * 对UDataFrame进行过滤（通用函数：传入lambda函数）
         * filter_ptr          返回符合条件的行地址
         * auto filtered_df = df.DF_filter([](const auto& item) { return item.width < 10; });
         */
        template<typename Predicate>
        MAYBE_USE bool filter(VecItemPtr& out_pointers, Predicate predicate) const;

        /**
         * @brief 使用谓词函数过滤数据项并返回新UDataFrame
         * @tparam Predicate 谓词函数类型
         * @param predicate 谓词函数
         * @return 符合条件的数据项构成的新UDataFrame对象
         */
        template<typename Predicate>
        UDataFrame DF_filter(Predicate predicate) const;


        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入Field：（TEXT,TEXT_SEP）, 以及筛选条件） 返回符合条件的UDataFrame(深复制)
        * loc_regex                 返回符合条件的UDataFrame
        * loc_[regex,_xyxy]         返回符合条件的UDataFrame, 筛选条件[regex, (>x0,y0; <x1,y1)]
        * loc_[regex,_x0x1]         返回符合条件的UDataFrame, 筛选条件[regex, (>x0; <x1)]
        * loc_[regex,_y0y1]         返回符合条件的UDataFrame, 筛选条件[regex, (>y0; <y1)]
        * loc_[regex,_x0y0]         返回符合条件的UDataFrame, 筛选条件[regex, (<x0; <y0)]
        * loc_[regex,_x1y1]         返回符合条件的UDataFrame, 筛选条件[regex, (>x1; >y1)]
        */
        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex(const RE2 &regex_) const {
            return DF_regex_match<field>(regex_);
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex(const RE2::Set& regex_set) const {
            return DF_regex_match<field>(regex_set);
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_grate(const int len) const {
            return DF_strlen_impl<field>(len, std::greater<>());
        }


        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_less(const int len) const {
            return DF_strlen_impl<field>(len, std::less<>());
        }


        template<Field field>
        MAYBE_USE UDataFrame DF_loc_strlen_equal(const int len) const {
            return DF_strlen_impl<field>(len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_grate(const RE2 &regex_, const int len) const {
            return DF_reg_len_cond<field>(regex_, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_equal(const RE2 &regex_, const int len) const {
            return DF_reg_len_cond<field>(regex_, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_less(const RE2 &regex_, const int len) const {
            return DF_reg_len_cond<field>(regex_, len, std::less<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_grate(const RE2::Set& regex_set, const int len) const {
            return DF_reg_len_cond<field>(regex_set, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_equal(const RE2::Set& regex_set, const int len) const {
            return DF_reg_len_cond<field>(regex_set, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_strlen_less(const RE2::Set& regex_set, const int len) const {
            return DF_reg_len_cond<field>(regex_set, len, std::less<>());
        }

        template<Field field>
        MAYBE_USE UDataFrame
        DF_loc_regex_xyxy(const RE2 &regex_, int x0, int y0, int x1, int y1) const {
            return DF_regex_cond<field>(regex_,
                                         [x0, y0, x1, y1](const DataItem &item) noexcept {
                                             return item.x0 > x0 && item.x1 < x1 && item.y0 > y0 && item.y1 < y1;
                                         });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0x1(const RE2 &regex_, int x0, int x1) const {
            return DF_regex_cond<field>(regex_,
                                         [x0, x1](const DataItem &item) noexcept { return item.x0 > x0 && item.x1 < x1; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_y0y1(const RE2 &regex_, int y0, int y1) const {
            return DF_regex_cond<field>(regex_,
                                         [y0, y1](const DataItem &item) noexcept { return item.y0 > y0 && item.y1 < y1; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_grate(const RE2 &regex_, int x0, int y0) const {
            return DF_regex_cond<field>(regex_,
                                         [x0, y0](const DataItem &item) noexcept { return item.x0 > x0 && item.y0 > y0; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_less(const RE2 &regex_, int x0, int y0) const {
            return DF_regex_cond<field>(regex_,
                                         [x0, y0](const DataItem &item) noexcept { return item.x0 < x0 && item.y0 < y0; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x1y1_less(const RE2 &regex_, int x1, int y1) const {
            return DF_regex_cond<field>(regex_,
                                         [x1, y1](const DataItem &item) noexcept { return item.x1 < x1 && item.y1 < y1; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0x1(const RE2::Set& regex_set, int x0, int x1) const {
            return DF_regex_cond<field>(regex_set,
                                         [x0, x1](const DataItem &item) noexcept { return item.x0 > x0 && item.x1 < x1; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_y0y1(const RE2::Set& regex_set, int y0, int y1) const {
            return DF_regex_cond<field>(regex_set,
                                         [y0, y1](const DataItem &item) noexcept { return item.y0 > y0 && item.y1 < y1; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_grate(const RE2::Set& regex_set, int x0, int y0) const {
            return DF_regex_cond<field>(regex_set,
                                         [x0, y0](const DataItem &item) noexcept { return item.x0 > x0 && item.y0 > y0; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x0y0_less(const RE2::Set& regex_set, int x0, int y0) const {
            return DF_regex_cond<field>(regex_set,
                                         [x0, y0](const DataItem &item) noexcept { return item.x0 < x0 && item.y0 < y0; });
        }

        template<Field field>
        MAYBE_USE UDataFrame DF_loc_regex_x1y1_less(const RE2::Set& regex_set, int x1, int y1) const {
            return DF_regex_cond<field>(regex_set,
                                         [x1, y1](const DataItem &item) noexcept { return item.x1 < x1 && item.y1 < y1; });
        }

        MAYBE_USE UDataFrame DF_loc_xyxy(int x0, int y0, int x1, int y1) const {
            auto condition = [x0, y0, x1, y1](const DataItem &item) noexcept -> bool {
                return item.x0 > x0 && item.y0 > y0 && item.x1 < x1 && item.y1 < y1;
            };
            return DF_xyxy_impl(condition);
        }

        MAYBE_USE UDataFrame DF_loc_x0x1(int x0, int x1) const {
            return DF_xyxy_impl([x0, x1](const DataItem &item) noexcept { return item.x0 > x0 && item.x1 < x1; });
        }

        MAYBE_USE UDataFrame DF_loc_y0y1(int y0, int y1) const {
            return DF_xyxy_impl([y0, y1](const DataItem &item) noexcept { return item.y0 > y0 && item.y1 < y1; });
        }

        MAYBE_USE UDataFrame DF_loc_x0y0(int x0, int y0) const {
            return DF_xyxy_impl([x0, y0](const DataItem &item) noexcept { return item.x0 > x0 && item.y0 > y0; });
        }

        MAYBE_USE UDataFrame DF_loc_x1y1(int x1, int y1) const {
            return DF_xyxy_impl([x1, y1](const DataItem &item) noexcept { return item.x1 < x1 && item.y1 < y1; });
        }

        MAYBE_USE UDataFrame DF_loc_x0_less(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.x0 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_y0_less(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.y0 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_x1_less(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.x1 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_y1_less(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.y1 < len; });
        }

        MAYBE_USE UDataFrame DF_loc_x0_grate(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.x0 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_y0_grate(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.y0 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_x1_grate(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.x1 > len; });
        }

        MAYBE_USE UDataFrame DF_loc_y1_grate(int len) const {
            return DF_xyxy_impl([len](const DataItem &item) noexcept { return item.y1 > len; });
        }


        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入Field：（TEXT,TEXT_SEP）, 以及筛选条件） 返回符合条件的地址
        * loc_regex             返回查找值是否为空, 第一个参数为筛选【DataItem的地址】
        * loc_[regex,_xyxy]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x0,y0; <x1,y1)]
        * loc_[regex,_x0x1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x0; <x1)]
        * loc_[regex,_y0y1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>y0; <y1)]
        * loc_[regex,_x0y0]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (<x0; <y0)]
        * loc_[regex,_x1y1]     返回查找值是否为空, 第一个参数为筛选【DataItem的地址】,筛选条件[regex, (>x1; >y1)]
        */

        template<Field field>
        MAYBE_USE bool loc_regex(VecItemPtr &out_ptr, const RE2 &regex_) const {
            return ptr_reg_impl<field>(out_ptr, VecRE2Ptr{&regex_});
        }

        template<Field field>
        MAYBE_USE bool loc_regex(VecItemPtr &out_ptr, const RE2::Set& regex_set) const {
            return ptr_reg_impl<field>(out_ptr, regex_set);
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_grate(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_equal(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE bool loc_strlen_less(VecItemPtr &out_ptr, const int len) const {
            return ptr_strlen_impl<field>(out_ptr, len, std::less<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_grate(VecItemPtr &out_ptr, const RE2 &regex_, const int len) const {
            return ptr_reg_len_cond<field>(out_ptr, regex_, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_equal(VecItemPtr &out_ptr, const RE2 &regex_, const int len) const {
            return ptr_reg_len_cond<field>(out_ptr, regex_, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_less(VecItemPtr &out_ptr, const RE2 &regex_, const int len) const {
            return ptr_reg_len_cond<field>(out_ptr, regex_, len, std::less<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_grate(VecItemPtr &out_ptr, const RE2::Set& regex_set, const int len) const {
            return ptr_reg_set_len_cond<field>(out_ptr, regex_set, len, std::greater<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_equal(VecItemPtr &out_ptr, const RE2::Set& regex_set, const int len) const {
            return ptr_reg_set_len_cond<field>(out_ptr, regex_set, len, std::equal_to<>());
        }

        template<Field field>
        MAYBE_USE bool loc_regex_strlen_less(VecItemPtr &out_ptr, const RE2::Set& regex_set, const int len) const {
            return ptr_reg_set_len_cond<field>(out_ptr, regex_set, len, std::less<>());
        }


        template<Field field>
        MAYBE_USE bool loc_regex_xyxy(VecItemPtr &out_ptr, const RE2 &regex_,
                                      int x0, int y0, int x1, int y1) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x0, y0, x1, y1](const DataItem &item) noexcept {
                return item.x0 > x0 && item.x1 < x1 && item.y0 > y0 && item.y1 < y1;
            });
        }


        template<Field field>
        MAYBE_USE bool loc_regex_x0_less(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.x0 < len;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0_grate(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.x0 > len;
                                          });
        }


        template<Field field>
        MAYBE_USE bool loc_regex_y0_less(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.y0 < len;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_y0_grate(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.y0 > len;
                                          });
        }


        template<Field field>
        MAYBE_USE bool loc_regex_x1_less(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.x1 < len;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x1_grate(VecItemPtr &out_ptr, const RE2 &regex_, int len) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [len](const DataItem &item) noexcept {
                                              return item.x1 > len;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0x1(VecItemPtr &out_ptr, const RE2 &regex_, int x0, int x1) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x0, x1](const DataItem &item) noexcept {
                                              return item.x0 > x0 && item.x1 < x1;
                                          });
        }


        template<Field field>
        MAYBE_USE bool loc_regex_x0_in(VecItemPtr &out_ptr, const RE2 &regex_, int x_min, int x_max) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x_min, x_max](const DataItem &item) noexcept {
                                              return item.x0 > x_min && item.x0 < x_max;
                                          });
        }


        template<Field field>
        MAYBE_USE bool loc_regex_y0_in(VecItemPtr &out_ptr, const RE2 &regex_, int y_min, int y_max) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [y_min, y_max](const DataItem &item) noexcept {
                                              return item.y0 > y_min && item.y0 < y_max;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_y0y1(VecItemPtr &out_ptr, const RE2 &regex_, int y0, int y1) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [y0, y1](const DataItem &item) noexcept {
                                              return item.y0 > y0 && item.y1 < y1;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0y0_grate(VecItemPtr &out_ptr, const RE2 &regex_, int x0, int y0) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x0, y0](const DataItem &item) noexcept {
                                              return item.x0 > x0 && item.y0 > y0;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0y0_less(VecItemPtr &out_ptr, const RE2 &regex_, int x0, int y0) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x0, y0](const DataItem &item) noexcept {
                                              return item.x0 < x0 && item.y0 < y0;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x1y1_less(VecItemPtr &out_ptr, const RE2 &regex_, int x1, int y1) const {
            return ptr_reg_cond<field>(out_ptr, regex_,
                                          [x1, y1](const DataItem &item) noexcept {
                                              return item.x1 < x1 && item.y1 < y1;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0x1(VecItemPtr &out_ptr, const RE2::Set& regex_set, int x0, int x1) const {
            return ptr_reg_cond<field>(out_ptr, regex_set,
                                          [x0, x1](const DataItem &item) noexcept {
                                              return item.x0 > x0 && item.x1 < x1;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_y0y1(VecItemPtr &out_ptr, const RE2::Set& regex_set, int y0, int y1) const {
            return ptr_reg_cond<field>(out_ptr, regex_set,
                                          [y0, y1](const DataItem &item) noexcept {
                                              return item.y0 > y0 && item.y1 < y1;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0y0_grate(VecItemPtr &out_ptr, const RE2::Set& regex_set, int x0, int y0) const {
            return ptr_reg_cond<field>(out_ptr, regex_set,
                                          [x0, y0](const DataItem &item) noexcept {
                                              return item.x0 > x0 && item.y0 > y0;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x0y0_less(VecItemPtr &out_ptr, const RE2::Set& regex_set, int x0, int y0) const {
            return ptr_reg_cond<field>(out_ptr, regex_set,
                                          [x0, y0](const DataItem &item) noexcept {
                                              return item.x0 > x0 && item.y0 > y0;
                                          });
        }

        template<Field field>
        MAYBE_USE bool loc_regex_x1y1_less(VecItemPtr &out_ptr, const RE2::Set& regex_set, int x1, int y1) const {
            return ptr_reg_cond<field>(out_ptr, regex_set,
                                          [x1, y1](const DataItem &item) noexcept {
                                              return item.x1 < x1 && item.y1 < y1;
                                          });
        }

        MAYBE_USE bool loc_xyxy(VecItemPtr &out_ptr, int x0, int y0, int x1, int y1) const {
            auto condition = [x0, y0, x1, y1](const DataItem &item) noexcept -> bool {
                return item.x0 > x0 && item.y0 > y0 && item.x1 < x1 && item.y1 < y1;
            };
            return this->filter(out_ptr, condition);
        }

        MAYBE_USE bool loc_x0x1(VecItemPtr &out_ptr, int x0, int x1) const {
            return this->filter(out_ptr, [x0, x1](const DataItem &item) noexcept {
                return item.x0 > x0 && item.x1 < x1;
            });
        }

        MAYBE_USE bool loc_x0_in(VecItemPtr &out_ptr, int x_min, int x_max) const {
            return this->filter(out_ptr, [x_min, x_max](const DataItem &item) noexcept {
                return item.x0 > x_min && item.x0 < x_max;
            });
        }

        MAYBE_USE bool loc_y0_in(VecItemPtr &out_ptr, int y_min, int y_max) const {
            return this->filter(out_ptr, [y_min, y_max](const DataItem &item) noexcept {
                return item.y0 > y_min && item.y0 < y_max;
            });
        }

        MAYBE_USE bool loc_y0y1(VecItemPtr &out_ptr, int y0, int y1) const {
            return this->filter(out_ptr, [y0, y1](const DataItem &item) noexcept {
                return item.y0 > y0 && item.y1 < y1;
            });
        }

        MAYBE_USE bool loc_x0y0(VecItemPtr &out_ptr, int x0, int y0) const {
            return this->filter(out_ptr, [x0, y0](const DataItem &item) noexcept {
                return item.x0 > x0 && item.y0 > y0;
            });
        }

        MAYBE_USE bool loc_x1y1(VecItemPtr &out_ptr, int x1, int y1) const {
            return this->filter(out_ptr, [x1, y1](const DataItem &item) noexcept {
                return item.x1 < x1 && item.y1 < y1;
            });
        }

        MAYBE_USE bool loc_x0_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x0 < len; });
        }


        MAYBE_USE bool loc_x0_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x0 > len; });
        }

        MAYBE_USE bool loc_y0_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y0 < len; });
        }


        MAYBE_USE bool loc_y0_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y0 > len; });
        }

        MAYBE_USE bool loc_x1_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x1 < len; });
        }

        MAYBE_USE bool loc_x1_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.x1 > len; });
        }

        MAYBE_USE bool loc_y1_less(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y1 < len; });
        }

        MAYBE_USE bool loc_y1_grate(VecItemPtr &out_ptr, int len) const {
            return this->filter(out_ptr, [len](const DataItem &item) noexcept { return item.y1 > len; });
        }

        /*
        * 对UDataFrame  进行索引筛选(默认索引按顺序排列)
        * DF_iloc       返回符合条件的行索引[0,2)的复制UDataFrame类,前闭后开
        * DV_iloc       返回符合条件的行索引[0,2)的视图UDataView类,前闭后开
        * iloc          返回符合条件的行地址[0,2),前闭后开
        */
        MAYBE_USE UDataFrame DF_iloc(int idx0, int idx1) const;

        MAYBE_USE UDataView DV_iloc(int idx0, int idx1) const;

        MAYBE_USE bool iloc(VecItemPtr &out_ptr, int idx0, int idx1) const;

        /*
        * 对UDataFrame进行过滤（具体过滤函数：传入具体数值）
        * - 输入 Field field_
        * - 输入 const VecRegex& regex_, int x0, int y0, int x1, int y1
        * - 返回值(符合条件的视图)：UDataView
        */
        template<Field field>
        MAYBE_USE UDataView DV_loc_regex(const RE2 &regex_) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex(const RE2::Set& regex_set) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_grate(const RE2::Set& regex_set, int len) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_equal(const RE2::Set& regex_set, int len) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_less(const RE2::Set& regex_set, int len) const;


        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_grate(const RE2 &regex_, int len) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_equal(const RE2 &regex_, int len) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_strlen_less(const RE2 &regex_, int len) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_xyxy(const RE2::Set& regex_set, int x0, int y0, int x1, int y1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0x1(const RE2::Set& regex_set, int x0, int x1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_y0y1(const RE2::Set& regex_set, int y0, int y1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0y0_grate(const RE2::Set& regex_set, int x0, int y0) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0y0_less(const RE2::Set& regex_set, int x0, int y0) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x1y1(const RE2::Set& regex_set, int x1, int y1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0x1(const RE2 &regex_, int x0, int x1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_y0y1(const RE2 &regex_, int y0, int y1) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0y0_grate(const RE2 &regex_, int x0, int y0) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x0y0_less(const RE2 &regex_, int x0, int y0) const;

        template<Field field>
        MAYBE_USE UDataView DV_loc_regex_x1y1_less(const RE2 &regex_, int x1, int y1) const;


        MAYBE_USE UDataView DV_loc_xyxy(int x0, int y0, int x1, int y1) const;

        MAYBE_USE UDataView DV_loc_x0x1(int x0, int x1) const;

        MAYBE_USE UDataView DV_loc_y0y1(int y0, int y1) const;

        MAYBE_USE UDataView DV_loc_x0y0_grate(int x0, int y0) const;

        MAYBE_USE UDataView DV_loc_x0y0_less(int x0, int y0) const;

        MAYBE_USE UDataView DV_loc_x1y1_less(int x1, int y1) const;

        MAYBE_USE UDataView DV_loc_x0_grate(int x0) const;

        MAYBE_USE UDataView DV_loc_x0_less(int x0) const;

        MAYBE_USE UDataView DV_loc_x1_less(int x1) const;

        MAYBE_USE UDataView DV_loc_y0_grate(int y0) const;

        MAYBE_USE UDataView DV_loc_y0_less(int y0) const;

        MAYBE_USE UDataView DV_loc_y1_less(int y1) const;

    private:
        void allocate(size_t new_capacity);

        void deallocate();

        void swap_data_frame(UDataFrame& other) noexcept;

        /////////////////////////////////////////////////////////////////////


        template<Field field>
        bool contains_impl(
            const std::unordered_set<std::string>& text_set,
            VecItemPtr* out_ptrs = nullptr,
            UDataFrame* out_df = nullptr) const;

        /////////////////////////////////////////////////////////////////////

        template<Field field, typename Comparator>
        MAYBE_USE static constexpr auto getCompare();

        ////////////////////////////////////////////////////////////////////////////////////////////////////

        template<Field field>
        MAYBE_USE UDataFrame DF_regex_match(const RE2::Set& regex_set) const;

        template<Field field>
        MAYBE_USE UDataFrame DF_regex_match(const RE2& regex) const;

        template<typename Predicate>
        MAYBE_USE UDataFrame DF_xyxy_impl(Predicate predicate) const;

        template<Field field, typename Comparator>
        MAYBE_USE UDataFrame DF_reg_len_cond(const RE2::Set &regex_set, size_t len, Comparator compare) const;

        template<Field field, typename Comparator>
        MAYBE_USE UDataFrame DF_reg_len_cond(const RE2& regex, size_t len, Comparator compare) const;

        template<Field field, typename Comparator>
        MAYBE_USE UDataFrame DF_strlen_impl(size_t len, Comparator compare) const;

        template<Field field, typename Predicate>
        MAYBE_USE UDataFrame DF_regex_cond(const RE2::Set& regex_set, Predicate predicate) const;

        template<Field field, typename Predicate>
        MAYBE_USE UDataFrame DF_regex_cond(const RE2& regex, Predicate predicate) const;


        //////////////////////////////////////////////////////////////////

        template<Field field>
        bool ptr_reg_impl(VecItemPtr &out_ptr, const RE2::Set& regex_set) const;

        template<Field field, typename Comparator>
        bool ptr_reg_set_len_cond(
            VecItemPtr& out_ptr, const RE2::Set& regex_set,
            size_t len, Comparator compare) const;

        template<Field field, typename Comparator>
        bool ptr_reg_len_cond(
            VecItemPtr& out_ptr, const RE2& regex_,
            size_t len, Comparator compare) const;

        template<Field field, typename Comparator>
        bool ptr_strlen_impl(VecItemPtr& out_ptr, size_t len, Comparator compare) const;

        template<Field field, typename Predicate>
        bool ptr_reg_cond(VecItemPtr& out_ptr, const RE2::Set& regex_set, Predicate predicate) const;

        template<Field field, typename Predicate>
        bool ptr_reg_cond(VecItemPtr& out_ptr, const RE2& regex_, Predicate predicate) const;

        //////////////////////////////////////////////////////////////////
        template<typename ConditionInt>
        MAYBE_USE UDataView DV_loc(ConditionInt conditionInt) const;

        template<Field field>
        MAYBE_USE UDataView dv_reg_impl(const RE2::Set& regex_set) const;

        template<Field field, typename Predicate>
        MAYBE_USE UDataView dv_reg_len_cond(
                const RE2::Set& regex_set, int len, Predicate predicate) const;

        template<Field field, typename Predicate>
        MAYBE_USE UDataView dv_reg_len_cond(
                const RE2& regex_, int len, Predicate predicate) const;

        template<Field field, typename Predicate>
        MAYBE_USE UDataView dv_reg_cond(
                const RE2::Set& regex_set, Predicate predicate) const;
    };
}

#include "UDataFrame.inl"
#endif //UDATAFRAME_H
